package com.foogui.boot.listener;

import com.foogui.boot.constant.RocketMqConstant;
import lombok.extern.java.Log;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.spring.annotation.RocketMQTransactionListener;
import org.apache.rocketmq.spring.core.RocketMQLocalTransactionListener;
import org.apache.rocketmq.spring.core.RocketMQLocalTransactionState;
import org.apache.rocketmq.spring.support.RocketMQHeaders;
import org.springframework.messaging.Message;

@Slf4j
@RocketMQTransactionListener(txProducerGroup = RocketMqConstant.SOURCE_GROUP)
public class TransactionListener implements RocketMQLocalTransactionListener {
    //arg就是生产者传过来的消息-对象类型，往往是DTO
    @Override
    public RocketMQLocalTransactionState executeLocalTransaction(Message msg, Object arg) {
        String transactionId = (String) msg.getHeaders().get(RocketMQHeaders.TRANSACTION_ID);
        //利用BeanUtils.copyProperties(dto, po)将arg转为po
        //操作数据库  eg. insert(po)
        try {
            log.info("本地事务执行正常,half消息可以投递让消费者消费了..");
        }catch (Exception e){
            e.printStackTrace();
            return RocketMQLocalTransactionState.ROLLBACK;
        }
        // 模拟事务回查机制
        // return RocketMQLocalTransactionState.UNKNOWN;
        return RocketMQLocalTransactionState.COMMIT;
    }
    //回查本地事务
    @Override
    public RocketMQLocalTransactionState checkLocalTransaction(Message msg) {
        String transactionId = (String) msg.getHeaders().get(RocketMQHeaders.TRANSACTION_ID);
       //根据transactionId去数据库select数据，如果result不为null，就说明本地事务已经执行，返回commit即可，反之；
        //需要说明的是按照唯一key去查也可以，没有事务id也可以实现效果
        Object result=new Object(); //模拟数据库查询结果
        if (result != null) {
            log.info("通过回查发现本地事务已经执行，消息可以投递..");
            return RocketMQLocalTransactionState.COMMIT;
        }
        return RocketMQLocalTransactionState.ROLLBACK;
    }
}
